package com.thghh.controller;

import cn.hutool.cache.Cache;
import cn.hutool.cache.impl.TimedCache;
import com.thghh.executor.MeantimeCompletionService;
import com.thghh.executor.Task;
import com.thghh.executor.TaskPoolScheduler;
import com.thghh.task.CountTask;
import com.thghh.task.StopCallable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * 包名称：com.thghh.controller
 * 类名称：TaskController
 * 类描述：
 * 创建人：@author pengzhikang
 * 创建时间：2021/9/3 13:36
 */
@Slf4j
@RestController
@RequestMapping("/task")
public class TaskController {

    @Autowired
    private TaskPoolScheduler taskScheduler;

    @PostMapping("/callTask/{count}")
    public String callTask(@PathVariable("count") int taskCount) throws Exception {
        MeantimeCompletionService service = taskScheduler.getMeantimeCompletionService(taskCount);
        List<Future> futureList = new ArrayList<>(taskCount);
        for (int i = 0; i < taskCount; i++) {
            Future<Long> future = service.submit(new CountTask());
            futureList.add(i, future);
        }
        service.await();

        StringBuilder sb = new StringBuilder();
        for (Future<Long> f : futureList) {
            Long v = f.get();
            sb.append(v).append("\n");
            log.info("return value {}", v);
        }

        return sb.toString();
    }

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /** Future缓存 */
    private Cache<Integer, Future<Void>> futureMap = new TimedCache<>(TimeUnit.MINUTES.toMillis(30));

    @GetMapping("/startTask/{id}")
    public String startTask(@PathVariable("id") int id) {
        Future<Void> future = threadPoolTaskExecutor.submit(this::call);
        stopTask(id);
        futureMap.put(id, future);
        return "启动任务" + id + "成功";
    }

    @GetMapping("/stopTask/{id}")
    public String stopTask(@PathVariable("id") int id) {
        Future<Void> future = futureMap.get(id);
        if (future != null) {
            futureMap.remove(id);
            future.cancel(true);
        }
        return "关闭任务" + id + "成功";
    }

    public Void call() throws Exception {
        while (true) {
            System.out.println("执行中...");
            // 用于取消时，可被中断。
            if (Thread.interrupted()) {
                log.info("任务被取消");
                break;
            }
        }
        return null;
    }

}
